package com.shuyun.ccms.encrypt.data.impl;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.shuyun.ccms.encrypt.common.*;
import com.shuyun.ccms.encrypt.data.EncryptProcessor;
import com.shuyun.ccms.encrypt.data.task.WriteCustomerInfoTask;
import com.shuyun.ccms.encrypt.util.ConnectionUtil;
import com.shuyun.ccms.encrypt.util.PropertyUtil;
import com.shuyun.ccms.encrypt.util.SqlFileExecutor;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.util.*;
import java.util.concurrent.*;

@Component
public class CheckDataProcessor{ //extends	EncryptProcessor {
	private static Logger logger = LoggerFactory.getLogger(CheckDataProcessor.class);
	private static Connection conn;

	// 每隔4小时执行一次
//	 @Scheduled(cron = "* * */5 * * ? ")

	// 每晚7点执行一次
	//@Scheduled(cron = "0 30 19 * * ? ")
	//测试用
	//@Scheduled(cron = "0 40 19 * * ? ")
//	@Override
	public static void execute() throws Exception {
		BufferedReader br = null;
		logger.info("加密信息校验开始.");
		long start = System.currentTimeMillis();
		int count = 1;
		String tenantId = null;
		List<String> errorTables = Lists.newArrayList();
		List<String> warnTables = Lists.newArrayList();
		 String reportFileDir = PropertyUtil.getValue("file.path")+File.separator+"report"+File.separator;
		String errorFileName = "error";
		String warnFileName = "warn";

		 List<String> targetTables = Lists.newArrayList();//需要校验的表名
		 targetTables.add(TargetTable.TAOBAO_CUSTOMER_INFO.getValue());
//		 targetTables.add(TargetTable.TAOBAO_ORDER.getValue());
//		 targetTables.add(TargetTable.DD_CUSTOMER_INFO.getValue());
//		 targetTables.add(TargetTable.DD_ORDER.getValue());
//		 targetTables.add(TargetTable.JD_CUSTOMER_INFO.getValue());
//		 targetTables.add(TargetTable.JD_ORDER.getValue());
//		 targetTables.add(TargetTable.YHD_CUSTOMER_INFO.getValue());
//		 targetTables.add(TargetTable.YHD_ORDER.getValue());
//		 targetTables.add(TargetTable.SUNING_CUSTOMER_INFO.getValue());

		 List<String> orignTables = Lists.newArrayList();//原始表名
		 orignTables.add(Table.TAOBAO.getValue());
		 orignTables.add(Table.TAOBAO_ORDER.getValue());
		 orignTables.add(Table.DD.getValue());
		 orignTables.add(Table.DD_ORDER.getValue());
		 orignTables.add(Table.JD.getValue());
		 orignTables.add(Table.JD_ORDER.getValue());
		 orignTables.add(Table.YHD.getValue());
		 orignTables.add(Table.YHD_ORDER.getValue());
		 orignTables.add(Table.SUNING.getValue());

		 Properties properties = new Properties();
		 properties.load(CheckDataProcessor.class.getClassLoader().getResourceAsStream("conf"+File.separator+"data.properties"));
		 List<String> targetTbCustomFiled = Arrays.asList(properties.getProperty("target_tb_custom").split(","));
		 List<String> targetTbOrderFiled = Arrays.asList(properties.getProperty("target_tb_order").split(","));
		 List<String> targetJdCustomFiled = Arrays.asList(properties.getProperty("target_jd_custom").split(","));
		 List<String> targetJdOrderFiled = Arrays.asList(properties.getProperty("target_jd_order").split(","));
		 List<String> targetDdCustomFiled = Arrays.asList(properties.getProperty("target_dd_custom").split(","));
		 List<String> targetDdOrderFiled = Arrays.asList(properties.getProperty("target_dd_order").split(","));
		 List<String> targetYhdCustomFiled = Arrays.asList(properties.getProperty("target_yhd_custom").split(","));
		 List<String> targetYhdOrderFiled = Arrays.asList(properties.getProperty("target_yhd_order").split(","));
		 List<String> targetSuningCustomFiled = Arrays.asList(properties.getProperty("target_suning_custom").split(","));

		 List<String> orignTbCustomFiled = Arrays.asList(properties.getProperty("orign_tb_custom").split(","));
		 List<String> orignTbOrderFiled = Arrays.asList(properties.getProperty("orign_tb_order").split(","));
		 List<String> orignJdCustomFiled = Arrays.asList(properties.getProperty("orign_jd_custom").split(","));
		 List<String> orignJdOrderFiled = Arrays.asList(properties.getProperty("orign_jd_order").split(","));
		 List<String> orignDdCustomFiled = Arrays.asList(properties.getProperty("orign_dd_custom").split(","));
		 List<String> orignDdOrderFiled = Arrays.asList(properties.getProperty("orign_dd_order").split(","));
		 List<String> orignYhdCustomFiled = Arrays.asList(properties.getProperty("orign_yhd_custom").split(","));
		 List<String> orignYhdOrderFiled = Arrays.asList(properties.getProperty("orign_yhd_order").split(","));
		 List<String> orignSuningCustomFiled = Arrays.asList(properties.getProperty("orign_suning_custom").split(","));

		 Map<String,List<String>> targetSelectFiledMap = Maps.newHashMap();
		 Map<String,List<String>> orignSelectFiledMap = Maps.newHashMap();
		 targetSelectFiledMap.put(TargetTable.TAOBAO_CUSTOMER_INFO.getValue(),targetTbCustomFiled);
		 targetSelectFiledMap.put(TargetTable.TAOBAO_ORDER.getValue(),targetTbOrderFiled);
		 targetSelectFiledMap.put(TargetTable.JD_CUSTOMER_INFO.getValue(),targetJdCustomFiled);
		 targetSelectFiledMap.put(TargetTable.JD_ORDER.getValue(),targetJdOrderFiled);
		 targetSelectFiledMap.put(TargetTable.DD_CUSTOMER_INFO.getValue(),targetDdCustomFiled);
		 targetSelectFiledMap.put(TargetTable.DD_ORDER.getValue(),targetDdOrderFiled);
		 targetSelectFiledMap.put(TargetTable.YHD_CUSTOMER_INFO.getValue(),targetYhdCustomFiled);
		 targetSelectFiledMap.put(TargetTable.YHD_ORDER.getValue(),targetYhdOrderFiled);
		 targetSelectFiledMap.put(TargetTable.SUNING_CUSTOMER_INFO.getValue(),targetSuningCustomFiled);

		 orignSelectFiledMap.put(Table.TAOBAO.getValue(),orignTbCustomFiled);
		 orignSelectFiledMap.put(Table.TAOBAO_ORDER.getValue(),orignTbOrderFiled);
		 orignSelectFiledMap.put(Table.JD.getValue(),orignJdCustomFiled);
		 orignSelectFiledMap.put(Table.JD_ORDER.getValue(),orignJdOrderFiled);
		 orignSelectFiledMap.put(Table.DD.getValue(),orignDdCustomFiled);
		 orignSelectFiledMap.put(Table.DD_ORDER.getValue(),orignDdOrderFiled);
		 orignSelectFiledMap.put(Table.YHD.getValue(),orignYhdCustomFiled);
		 orignSelectFiledMap.put(Table.YHD_ORDER.getValue(),orignYhdOrderFiled);
		 orignSelectFiledMap.put(Table.SUNING.getValue(),orignSuningCustomFiled);




		try{
			String tenantFile = PropertyUtil.getValue("tenantId.path");
			br = new BufferedReader(new InputStreamReader(new FileInputStream(tenantFile)));
			tenantId = br.readLine();
			while(tenantId != null){
				long tenantStart = System.currentTimeMillis();
				//step1: get conn
				conn = ConnectionUtil.newInstance().getTenantConn(tenantId);
		    	// step 2: 校验plt_taobao_custom
				boolean checkRelData = DataCheck.checkRelationTableData(conn, TargetTable.TAOBAO_CUSTOMER_INFO.getValue());
				if(checkRelData){
					for (int m =0; m < targetTables.size(); m++){
						String targetTable = targetTables.get(m);
						String orignTable = orignTables.get(m);
						boolean isOk = DataValid.checkInfo(conn,targetTable,targetSelectFiledMap.get(targetTable),orignTable,orignSelectFiledMap.get(orignTable));
						if (!isOk){//校验taobao custom，写失败文件
							errorTables.add(tenantId+":"+targetTable);
						}
						if (!DataValid.checkCount(conn,orignTable,targetTable)){//校验taobao custom count，写warn文件
							warnTables.add(tenantId+":"+targetTable);
						}
					}
				} else{//plt_taobao_custom无数据，直接写error文件，并退出循环
					errorTables.add(tenantId);
				}
				long tenantEnd = System.currentTimeMillis();
				logger.info("第 " + count +  " 个租户: " + tenantId + "加密信息校验结束,耗时:" + (tenantEnd - tenantStart)/1000 +" s");
				tenantId = br.readLine();
				count++;
			}
			long end = System.currentTimeMillis();
			logger.info("====== 所有租户加密校验结束.总耗时: "+ (end-start)/1000 +" s,共加密: " + (count-1) + "个租户");
		}catch(Exception e){
			logger.info("加密校验失败. tenantId: " + tenantId +",error:" + e.getMessage());
			throw e;
		}finally{
			ConnectionUtil.newInstance().closeConn(conn);
			if(br != null){
				br.close();
			}
			FileUtils.writeLines(new File(reportFileDir + errorFileName),errorTables);
			FileUtils.writeLines(new File(reportFileDir + warnFileName),warnTables);
		}
	}


	public static void main(String args[]){
		try {
			execute();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
